package data.request
{
	import data.DataPack;
	import data.DataTransferType;
	import data.events.RequestBaseEvent;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	
	public class RequestData extends EventDispatcher
	{
		/**
		 *是否在加载中 
		 */		
		private var _isLoading:Boolean;
		
		/**
		 *待加载队列 
		 */		
		private var _requestQueue:Vector.<RequestBase>;
		
		/**
		 *正在加载中队列 
		 */		
		private var _requestQueueLoading:Vector.<RequestBase>;
		
		public function RequestData()
		{
			_requestQueue=new Vector.<RequestBase>();
			_requestQueueLoading=new Vector.<RequestBase>();
		}
		
		public function sendRequestPack(dataPack:DataPack):void
		{
			var requestBase:RequestBase=new RequestBase(dataPack.requestUrl, dataPack.data, dataPack.requestMethodType);
			
			//增加至Request队列 
			_requestQueue.push(requestBase);

			if(!_isLoading)
			{
				configQueue();
				loadQueue();
			}
		}
		
		/**
		 *配置队列 
		 */		
		private function configQueue():void
		{
			for(var i:int=0;i<_requestQueue.length && _requestQueueLoading.length<=3;i++)
			{	
				_requestQueueLoading.push(_requestQueue[i]);
				_requestQueue.splice(_requestQueue.indexOf(_requestQueue[i]), 1);
			}
		}
		
		/**
		 *加载队列 
		 */		
		private function loadQueue():void
		{
			for(var i:int=0;i<_requestQueueLoading.length;i++)
			{
				_isLoading=true;
				execute(_requestQueueLoading[i]);
			}
		}
		
		/**
		 *执行某个请求
		 */		
		private function execute(requestBases:RequestBase):void
		{
			requestBases.urlLoader.addEventListener(Event.COMPLETE, onComplete);
			requestBases.urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
			requestBases.urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
			requestBases.urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onError);
			requestBases.urlLoader.load(requestBases.request);
		}
		
		/**
		 * Request队列中的某个请求完成后
		 */
		private function onComplete(evt:Event):void
		{
			var requestBase:RequestBase=evt.currentTarget as RequestBase;
			if(requestBase)
			{
				var data:Object=new Object();
				data["rootPackCode"]=requestBase.rootPackCode;
				data["packCode"]=requestBase.packCode;
				data["data"]=requestBase.urlLoader.data;
				
				dispatchEvent(new RequestBaseEvent(RequestBaseEvent.REQUEST_DATA, data));

				_requestQueueLoading.splice(_requestQueueLoading.indexOf(requestBase), 1);//从队列中移除当前已经成功的Request
				requestBase.dispose();
			}
			requestBase=null;
			
			if(_requestQueue.length<=0 && _requestQueueLoading.length<=0)
			{
				_isLoading=false;
			}

			configQueue();
		}
		
		private function onError(evt:Event):void
		{
			var requestBase:RequestBase=evt.currentTarget as RequestBase;
			if(requestBase)
			{
				switch(evt)
				{
					case evt is IOErrorEvent:
					case evt is SecurityErrorEvent:
						requestBase.loadCount+=1;
						break;
					case evt is HTTPStatusEvent:
						var hsEvt:HTTPStatusEvent=evt as HTTPStatusEvent;
						if(hsEvt && (hsEvt.status==0 || hsEvt.status==404))
						{
							requestBase.loadCount+=1;
						}
						break;
				}

				if(requestBase.loadCount>=3)
				{//如果重新加载3次均失败，则永久放弃此加载请求
					_requestQueueLoading.splice(_requestQueueLoading.indexOf(requestBase), 1);
					var data:Object=new Object();
					data["rootPackCode"]=requestBase.rootPackCode;
					data["packCode"]=requestBase.packCode;
					data["event"]=evt;
					
					//发出错误事件
					switch(evt)
					{
						case evt is IOErrorEvent:
							dispatchEvent(new RequestBaseEvent(RequestBaseEvent.IO_ERROR, data));
							break;
						case evt is SecurityErrorEvent:
							dispatchEvent(new RequestBaseEvent(RequestBaseEvent.SECURITY_ERROR, data));
							break;
						case evt is HTTPStatusEvent:
							var hsEvt2:HTTPStatusEvent=evt as HTTPStatusEvent;
							if(hsEvt2 && (hsEvt2.status==0 || hsEvt2.status==404))
							{
								dispatchEvent(new RequestBaseEvent(RequestBaseEvent.HTTPSTATUS_ERROR, data));
							}
							break;
					}
					
					requestBase.dispose();
					requestBase=null;
				}
			}
			
			configQueue();
		}
	}
}